#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <pthread.h>
#include <unistd.h>
#include <time.h>

//编译
//gcc cas_test.c -lpthread -lm

#define IF_USE_MUTEX 0

#define COMPUTE_TIMES (1000 * 1000)

volatile uint64_t val = 0;

uint32_t get_tick_count_ms(void)
{
    struct timespec tp;

    clock_gettime(CLOCK_MONOTONIC,&tp);

    return (tp.tv_sec * 1000 + tp.tv_nsec / 1000000);
}

#if IF_USE_MUTEX

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

//互斥锁方式
void *add(void *para)
{
    (void)para;

    pthread_mutex_lock(&mutex);
    for(volatile uint64_t i = 0;i < COMPUTE_TIMES;i++)
    val++;
    pthread_mutex_unlock(&mutex);

    return (void *)1;
}

#else

//CAS方式
void *add(void *para)
{
    (void)para;
    register uint64_t back,expect;

    for(volatile uint64_t i = 0;i < COMPUTE_TIMES;i++)
    {
        do{
            back = val;
            expect = val + 1;
        }while(!__sync_bool_compare_and_swap(&val,back,expect));
    }

    return (void *)1;
}

#endif/*IF_USE_MUTEX*/

int main(int argc,char *argv[])
{
    pthread_t thd;
    uint32_t tick_start = 0,tick_end = 0;

    #if IF_USE_MUTEX
    pthread_mutex_init(&mutex,NULL);
    #endif

    tick_start = get_tick_count_ms();
    printf("tick_start:%u\r\n",tick_start);

    pthread_create(&thd,NULL,add,NULL);

    add(NULL);

    //确保线程已经执行完
    pthread_join(thd,NULL);

    tick_end = get_tick_count_ms();
    printf("tick_end:%u\r\n",tick_end);

    printf("time:%ums\r\n",tick_end - tick_start);

    printf("%lu\r\n",val);

    return 0;
}
